package com.yueke.gemini.datasources.mongodb;
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.mongodb.BasicDBObject;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
/**
 * activity  mongodb数据源
 * @author qxw
 * 2017年10月30日
 */
@Component
public class ActivityMongodbService {

		@Autowired
	    @Qualifier("activityMongoTemplate")
	    private MongoTemplate mongoTemplate;

		 /**
	     * 获取集合链接
	     * @param collectionName   表名
	     * @return
	     * 2017年10月25日
	     */
	    public MongoCollection<Document> getCollection(String collectionName){
	    	return mongoTemplate.getCollection(collectionName);
			
	    }
	    
	    /**
	     *查询单条数据
	     * @param collectionName  表名
	     * @param query   查询条件
	     * @return
	     * 2017年10月25日
	     */
		public Document   findOne(String collectionName,BasicDBObject query){
			return getCollection(collectionName).find(query).first();
	    }
	    
		
		/**
		 * 查询集合
		 * @param collectionName 表名
		 * @param query   查询条件
		 * @return
		 * 2017年10月25日
		 */
		public List<JSONObject>  findAll(String collectionName,BasicDBObject query){
			List<JSONObject> list=new ArrayList<>();
			FindIterable<Document> cursor=getCollection(collectionName).find(query);
			MongoCursor<Document> iterator = cursor.iterator();
			while(iterator.hasNext()){ 
				Document doc=iterator.next();
				list.add(JSON.parseObject(diyObjectIdToJson(doc))); 
			}
			return list;
	    }
		
		/**
		 * 查询记录数
		 * @param collectionName  表名
		 * @param query       查询条件
		 * @return
		 * 2017年10月25日
		 */
		public long getCount( String collectionName, BasicDBObject query){
			return getCollection(collectionName).count(query);
		}
		
		
		/**
		 * 分页查询
		 * @param collectionName    表名
		 * @param query				查询条件
		 * @param pageNum			页数
		 * @param pageSize			条数
		 * @param sort				排序字段
		 * @return
		 * 2017年10月25日
		 */
		public JSONObject getPage(String collectionName,BasicDBObject query,int pageNum,int pageSize,BasicDBObject sort){
			JSONObject page=new JSONObject();
			long totalCount=getCount(collectionName, query);
			long totalPage = (int)(totalCount/pageSize + ((totalCount % pageSize== 0) ? 0 : 1));  
			page.put("pageNum",pageNum);
			page.put("pageSize",pageSize);
			page.put("totalCount",totalCount);
			page.put("totalPage",totalPage);
			List<JSONObject> list=new ArrayList<JSONObject>();
			if(totalCount>0){
				int startRow=pageNum>0?(pageNum - 1)*pageSize:0;  
				FindIterable<Document> result=getCollection(collectionName).find(query).sort(sort).skip(startRow).limit(pageSize);
				MongoCursor<Document> iterator = result.iterator();
				while(iterator.hasNext()){ 
					Document doc=iterator.next();
					list.add(JSON.parseObject(diyObjectIdToJson(doc))); 
				}
			}
			page.put("data",list);
			return page;
		}
		
		
		/**
		 * 修改
		 * @param collectionName   表名
		 * @param query			        查询条件	
		 * @param update		       修改参数	
		 * 2017年10月25日
		 */
		public void update(String collectionName,BasicDBObject filter,Document update){
			 getCollection(collectionName).updateOne(filter, update);
			
		}
		    
		/**
		 * 删除
		 * @param collectionName    表名
		 * @param query				 删除条件	
		 * 2017年10月25日
		 */
		public void deleteByName(String collectionName,BasicDBObject query){
			 getCollection(collectionName).deleteOne(query);
			
		}
		
		/**
		 * 删除整张表
		 * @param collectionName
		 * 2017年10月25日
		 */
		public void drop(String collectionName){
			 getCollection(collectionName).drop();
		}
		
		/**
		 * 添加
		 * @param collectionName
		 * @param document
		 * 2017年10月25日
		 */
		public void save(String collectionName, Document document){
			 getCollection(collectionName).insertOne(document);
		}
		
		
		/**
		 * 聚合函数查询
		 * @param collectionName  表名
		 * @param aggregation   分组条件  Aggregation.group(分组字段,筛选条件,sum函数等等),Aggregation.project(指定显示字段)
		 * @return
		 * 2017年10月26日
		 */
		public List<JSONObject> findAggregate(String collectionName,Aggregation aggregation){
			List<JSONObject> list=new ArrayList<>();
			AggregationResults<BasicDBObject> aggRes = mongoTemplate.aggregate(aggregation,collectionName, BasicDBObject.class);
			List<BasicDBObject> listRes = aggRes.getMappedResults();
			for (BasicDBObject dBObject: listRes){
				list.add(JSON.parseObject(diyObjectIdToJson(dBObject))); 
			}
			return list;
		}
		
		
	    /**
	     * 出库后查询
	     * @param object
	     * @return
	     */
	    public static final String diyObjectIdToJson( Object object){
	    	 return JSON.toJSONString(object,objectIdSerializer,
	    			 SerializerFeature.WriteDateUseDateFormat,
	         		SerializerFeature.WriteNullNumberAsZero,
	         		SerializerFeature.WriteMapNullValue,
	         		SerializerFeature.WriteNullStringAsEmpty); 
	    }
	    
	    private static SerializeFilter  objectIdSerializer = new ValueFilter  () {
			@Override
			public Object process(Object object, String name, Object value){
				 if ("_id".equals(name)) {
					 if (value instanceof ObjectId){ return value.toString();  }
				}
				return value;
			}
	    };
}
